package com.xncoding.async.controller;

import org.redisson.Redisson;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import com.google.common.util.concurrent.RateLimiter;
import com.xncoding.async.service.RedisLockService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Controller
public class TestCrontroller {

	@Autowired
	@Qualifier("strKeyRedisTemplate")
	private RedisTemplate redisClient;

	@Autowired
	private Redisson redisson; // 假设Redisson客户端已经配置好

	@Autowired
	private RedissonClient redissonClient;
	@Autowired
	private RedisLockService redisLockUtil;
	@Autowired
	private RedisLockRegistry redisLockRegistry;
	@RequestMapping("/testhaskey")
	public @ResponseBody String simpleSet() throws Exception {
		String mpno = "111111";
		System.out.println(redisClient.hasKey(mpno));
		System.out.println(redisClient.hasKey(mpno));
		if (redisClient.hasKey(mpno)){
			throw new  Exception("异常");
		}else {
			System.out.println(redisClient.opsForValue().setIfAbsent(mpno, "1",30L, TimeUnit.SECONDS));; //枷锁
			System.out.println(redisClient.opsForValue().setIfAbsent(mpno, "1",30L, TimeUnit.SECONDS));; //枷锁
			//业务
		}



		return "success";
	}


	@RequestMapping("/send")
	public  @ResponseBody String sendSms(@RequestParam("userId") String userId) {
		// 根据用户ID生成限流键
		String minuRey = "sms:minu:" + userId;
		String hourkey = "sms:hour:" + userId;

		// 获取或创建限流器
		RRateLimiter minuReyLimiter = redisson.getRateLimiter(minuRey);
		RRateLimiter hourkeyLimiter = redisson.getRateLimiter(hourkey);

		// 设置限流规则：每秒允许1次请求，滑动窗口去时间为1分钟
		minuReyLimiter.trySetRate(RateType.OVERALL, 1, 5, RateIntervalUnit.SECONDS);
		hourkeyLimiter.trySetRate(RateType.OVERALL, 3, 1, RateIntervalUnit.DAYS);
		// 尝试获取令牌，如果成功则返回发送成功，否则返回发送失败
		if (minuReyLimiter.tryAcquire() ) {
			// 发送短信逻辑（调用第三方短信接口）
			if (hourkeyLimiter.tryAcquire()){
				return "短信发送成功";
			}else {
				return "11短信发送失败，请稍后再试";
			}
		} else {
			return "短信发送失败，请稍后再试";
		}
	}

	@RequestMapping("/testhaskey00")
	public @ResponseBody String simpleSet00() throws Exception {
		final RLock lock = redissonClient.getLock("lock_key");
		try {
			// 等待获取锁时间10秒，20秒后自动解锁
//			boolean res = lock.tryLock(10, 20, TimeUnit.SECONDS);
			boolean res = lock.tryLock();
			if (res){
				throw new Exception("异常了");
			}else {
				//            lock.lock();
				lock.lock( 20, TimeUnit.SECONDS);
				lock.lock( 20, TimeUnit.SECONDS);
				System.out.println(lock.tryLock());
				// 执行业务逻辑
				System.out.println("业务执行玩了");
			}

		} catch (Exception e) {
			throw new Exception(e);
		} finally {
//			lock.unlock();
		}



		return "success";
	}


	@GetMapping("/performTask")
	public String performTask() {
		String lockKey = "taskLock";
		String requestId = UUID.randomUUID().toString(); // 用于标识请求的唯一性（在实际应用中，你可能需要更复杂的逻辑来生成requestId）

		// 尝试获取锁
		boolean locked = redisLockUtil.tryLock(lockKey, requestId);
		if (locked) {
			try {
				// 执行需要同步的任务
				System.out.println("Task is being performed by " + requestId);
				// 模拟任务执行时间
				Thread.sleep(20000);
				return "Task completed successfully";
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
				return "Task was interrupted";
			} finally {
				// 释放锁
				redisLockUtil.unlock(lockKey, requestId);
			}
		} else {
			return "Task could not be performed because the lock was not acquired";
		}
	}
	@GetMapping("/redis")
	public void test1() {
		Lock lock = redisLockRegistry.obtain("redis");
		try{
			//尝试在指定时间内加锁，如果已经有其他锁锁住，获取当前线程不能加锁，则返回false，加锁失败；加锁成功则返回true
			if(lock.tryLock(3, TimeUnit.SECONDS)){
				System.out.println("lock is ready");
				TimeUnit.SECONDS.sleep(5);
			}
		} catch (InterruptedException e) {
			System.out.println("obtain lock error");
			System.out.println(e);
		} finally {
			lock.unlock();
		}
	}


}
